﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using Danser_Entity.Entities;
using Danser_Entity.Queries.Data;

namespace Danser_Control.Managers
{
    /// <summary>
    /// Provide access to the Danser persistance layer 
    /// </summary>
    public interface IDBManager
    {
        /* Methods to add new data */
        /// <summary>
        /// Adds a new user to the DB
        /// </summary>
        /// <param name="user">User to add. UserID must be unique.</param>
        void AddUser(User user);
        /// <summary>
        /// Adds the user query.
        /// Note - the field ID in the query will be ignored - the DB is responsible to determine its value
        /// </summary>
        /// <param name="query"></param>
        void AddUserQuery(UserQuery query);
        /// <summary>
        /// Adds the given validation template
        /// Note - the field ID in the template will be ignored - the DB is responsible to determine its value
        /// </summary>
        /// <param name="template"></param>
        void AddValidationTemplate(ValidationTemplate template);
        /// <summary>
        /// Adds the test
        /// </summary>
        /// <param name="test"></param>
        /// <exception cref="Danser_Control.Exceptions.DanserDuplicateKeyException">
        /// thrown when trying to insert to DB a key that is already exists</exception>
        void AddTestInfo(TestInfo test);
        /// <summary>
        /// Adds a test params. A TestInfo with the testInfoIndex must already exist, otherwise operation will fail.
        /// Note - the field testParamsIndex in the test will be ignored - the DB is responsible to determine its value
        /// </summary>
        /// <param name="tParams"></param>
        /// <returns>testParamsIndex that was generated by the DB for this object</returns>
        int AddTestParams(TestParams tParams);
        /// <summary>
        /// Adds test results.
        /// Note - a TestInfo with id testInfoIndex and TestParams with testParamsIndex must already exist, otherwise operation will fail.
        /// </summary>
        /// <param name="results"></param>
        void AddTestResults(TestResults results);
        /// <summary>
        /// Adds a set of test results. See AddTestResults(TestResults results) for more info.
        /// </summary>
        /// <param name="tests"></param>
        void AddTests(List<TestResults> tests);

        /* Methods to remove new data */
        /// <summary>
        /// Deletes the user and ALL queries he has
        /// </summary>
        /// <param name="UserID">
        /// unique user identifier
        /// </param>
        void DeleteUser(String UserID);
        /// <summary>
        /// Deletes given user query
        /// </summary>
        /// <param name="queryID"></param>
        void DeleteUserQuery(int queryID);
        /// <summary>
        /// Deletes the validation template and removes all test failures indication for that template.
        /// </summary>
        /// <param name="templateID"></param>
        void DeleteValidationTemplate(int templateID);
        /// <summary>
        /// Deletes the test and ALL the params and results it has
        /// </summary>
        /// <param name="testInfoIndex">
        /// unique test identifier
        /// </param>
        void DeleteTestInfo(String testInfoIndex);
        /// <summary>
        /// Deletes the test params (ONLY if there are no results with this params, otherwise operation will fail)
        /// </summary>
        /// <param name="testInfoIndex">
        /// unique test identifier
        /// </param>
        /// <param name="testParamsIndex">
        /// unique parameters identifier
        /// </param>
        void DeleteTestParams(String testInfoIndex, int testParamsIndex);
        /// <summary>
        /// Deletes the test results with the given keys
        /// </summary>
        /// <param name="testInfoIndex"></param>
        /// <param name="testParamsIndex"></param>
        /// <param name="attenuation"></param>
        void DeleteTestResults(String testInfoIndex, int testParamsIndex, int attenuation);

        /* Methods to modify existing data */
        /// <summary>
        /// Modifies user's permission level
        /// </summary>
        /// <param name="UserID"></param>
        /// <param name="newPermission"></param>
        void SetUserPermission(String UserID, PermissionLevel newPermission);
        /// <summary>
        /// Sets a test confirmation status
        /// </summary>
        /// <param name="testInfoIndex"></param>
        /// <param name="isConfirmed"></param>
        void ConfirmTest(String testInfoIndex, bool isConfirmed);
        /// <summary>
        /// Sets a test anchor status
        /// </summary>
        /// <param name="testInfoIndex"></param>
        /// <param name="isAnchor"></param>
        void AnchorTest(String testInfoIndex, bool isAnchor);
        /// <summary>
        /// Modifies given template details
        /// </summary>
        /// <param name="templateID"></param>
        /// <param name="MailList"></param>
        /// <param name="appliedOnDefault"></param>
        void ModifyTemplateDetails(int templateID, String MailList, bool appliedOnDefault);

        /* Query methods */
        /// <summary>
        /// This method should be used for general queries which are not covered by 
        /// other methods in the interface (i.e. join)
        /// </summary>
        /// <param name="sqlQuery"></param>
        /// <returns></returns>
        SqlDataReader PerformQuery(String sqlQuery);
        /// <summary>
        /// Returns the User object with the given userID, null if not exist
        /// </summary>
        /// <param name="userID"></param>
        /// <returns></returns>
        User GetSpecificUser(String userID);
        /// <summary>
        /// Returns the TestInfo object with the given testInfoIndex, null if not exist
        /// </summary>
        /// <param name="testInfoIndex"></param>
        /// <returns></returns>
        TestInfo GetTest(String testInfoIndex);
        /// <summary>
        /// Returns all UserQuery objects that belong to the user with the given userID
        /// </summary>
        /// <param name="userID"></param>
        /// <returns></returns>
        List<UserQuery> GetAllUserQueries(String userID);
        /// <summary>
        /// Returns the TestParams object with the given id
        /// </summary>
        /// <param name="testInfoIndex"></param>
        /// <param name="testParamsIndex"></param>
        /// <returns></returns>
        TestParams GetTestParams(String testInfoIndex, int testParamsIndex);
        /// <summary>
        /// Returns the TestResults object with the given id
        /// </summary>
        /// <param name="testInfoIndex"></param>
        /// <param name="testParamsIndex"></param>
        /// <param name="attenuation"></param>
        /// <returns></returns>
        TestResults GetTestResults(String testInfoIndex, int testParamsIndex, int attenuation);
        /// <summary>
        /// Returns the ValidationTemplate object with the given id
        /// </summary>
        /// <param name="templateID"></param>
        /// <returns></returns>
        ValidationTemplate GetValidationTemplate(int templateID);
        /// <summary>
        /// Returns a list of TestIntegratedData that applies to given rule
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        IList<TestIntegratedData> GetTestData(String filter);

        /* query methods for each table with filter condition: */
        /// <summary>
        /// Returns all ValidationTemplate objects that satisfy given filtering condition
        /// </summary>
        /// <param name="filter">Filtering condition in SQL syntax</param>
        /// <returns></returns>
        List<ValidationTemplate> GetValidationTemplates(String filter);
        /// <summary>
        /// Returns all User objects that satisfy given filtering condition
        /// </summary>
        /// <param name="filter">Filtering condition in SQL syntax</param>
        /// <returns></returns>
        List<User> GetUsers(String filter);
        /// <summary>
        /// Returns all UserQuery objects that satisfy given filtering condition
        /// </summary>
        /// <param name="filter">Filtering condition in SQL syntax</param>
        /// <returns></returns>
        List<UserQuery> GetQueries(String filter);
        /// <summary>
        /// Returns all TestResults objects that satisfy given filtering condition
        /// </summary>
        /// <param name="filter">Filtering condition in SQL syntax</param>
        /// <returns></returns>
        List<TestResults> GetTestResults(String filter);
        /// <summary>
        /// Returns all TestParams objects that satisfy given filtering condition
        /// </summary>
        /// <param name="filter">Filtering condition in SQL syntax</param>
        /// <returns></returns>
        List<TestParams> GetTestParams(String filter);
        /// <summary>
        /// Returns all TestInfo objects that satisfy given filtering condition
        /// </summary>
        /// <param name="filter">Filtering condition in SQL syntax</param>
        /// <returns></returns>
        List<TestInfo> GetTestInfo(String filter);


        /* Test validation methods */
        /// <summary>
        /// Validates a test against given condition
        /// </summary>
        /// <param name="testInfoIndex">index of test to validate</param>
        /// <param name="validationCondition">SQL Expression representing validation condition</param>
        /// <returns>true if test passes validation condition, false otherwise</returns>
        bool ValidateTest(String testInfoIndex, String validationCondition);
        /// <summary>
        /// Marks a test as failed, by the given ValidationTemplate
        /// </summary>
        /// <param name="validationTemplateID"></param>
        /// <param name="testInfoIndex"></param>
        void SetFailedTest(int validationTemplateID, String testInfoIndex);
        /// <summary>
        /// Returns all tests that failed validation by the given ValidationTemplate
        /// </summary>
        /// <param name="validationTemplateID"></param>
        /// <returns></returns>
        List<TestInfo> GetFailedTestForTemplate(int validationTemplateID);
        /// <summary>
        /// Returns all ValidationTemplate objects which failed the given test's validation
        /// </summary>
        /// <param name="testInfoIndex"></param>
        /// <returns></returns>
        List<ValidationTemplate> GetFailingTemplatesForTest(String testInfoIndex);









    }
}
